package com.ly.crawl.impl;

import com.ly.crawl.Capturer;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.util.LinkedHashMap;
import java.util.Map;

public class SimpleDataCapturer implements Capturer<Map<String, Object>> {
    private Map<String, String> nacs = new LinkedHashMap<>();

    /**
     * @param urlRegex
     * @param nameAndCssSelects 格式参考:<br>
     *                          1. CSS选择器                            获取text<br>
     *                          2. CSS选择器==>html                     获取html<br>
     *                          3. CSS选择器==>属性                      获取属性值<br>
     *                          4. CSS选择器==>属性(正则表达式带一个())     获取属性值,并提取分组1的值<br>
     *                          5. ==>字面值                            返回字面值<br>
     *                          6. url(正则表达式第一个())                获取当前地址中的分组1的值<br>
     *                          7. CSS选择器==>script                   获取js代码<br>
     *                          8. 找不到CSS选择器的元素返回 null
     */
    public SimpleDataCapturer(String... nameAndCssSelects) {
        for (int i = 0; i < nameAndCssSelects.length; i += 2) {
            nacs.put(nameAndCssSelects[i], nameAndCssSelects[i + 1]);
        }
    }

    public SimpleDataCapturer(Map<String, String> nacs) {
        this.nacs.putAll(nacs);
    }

    @Override
    public Map<String, Object> capture(String url, Document doc) {
        Map<String, Object> data = new LinkedHashMap<>();
        for (Map.Entry<String, String> nc : nacs.entrySet()) {
            String value;
            if (nc.getValue() == null || nc.getValue().trim().isEmpty()) {
                value = null;
            } else if (nc.getValue().matches("url\\(.+\\)")) {
                String regex = nc.getValue().replaceAll("url\\((.+)\\)", "$1");
                value = url.replaceAll(regex, "$1");
            } else {
                value = captureData(doc, nc.getValue());
            }
            //  判断必须不为空项目(必填项)
            String name = nc.getKey();
            if (name.endsWith("*")) {
                if (value == null && value.trim().isEmpty()) {
                    return null;
                } else {
                    name = name.substring(0, name.length() - 1);
                }
            }
            data.put(name, value);
        }
        data.put("url", url);
        return data;
    }

    private String captureData(Document doc, String cssSelecter) {
        String[] items = cssSelecter.split("==>");
        if (items[0].trim().isEmpty()) {
            return items[1];
        } else {
            Element e = doc.selectFirst(items[0]);
            if (e == null) {
                return null;
            }
            return items.length == 1 ? getValue(e, null) : getValue(e, items[1]);
        }
    }
}
